;; (println "hello world")
;; update a string
;; all express in  function
(defn- update-string 
  []
  (let [s (atom "string")]
    (println @s)
    (reset! s "update-string")
    (println @s)))

;; (update-string)

(defn- update-vec
  []
  (let [v (atom [1 2 3])]
    (reset! v [1 2 3 4])
    (println @v)))

(update-vec)
;; 545<(78 )
;;

;; 545<(7890)
user=> (def users [{:name "James" :age 26}  {:name "John" :age 43}])
user=> (assoc-in users [1 :age] 44)
[{:name "James", :age 26} {:name "John", :age 44}]
 
user=> (assoc-in users [1 :password] "nhoJ")
[{:name "James", :age 26} {:password "nhoJ", :name "John", :age 43}]

;; Also (assoc m 2 {...}) or (conj m {...})
user=> (assoc-in users [2] {:name "Jack" :age 19}) 
[{:name "James", :age 26} {:name "John", :age 43} {:name "Jack", :age 19}]

;; From http://clojure-examples.appspot.com/clojure.core/assoc-in
(def ppl (atom {"persons" {"joe" {:age 1}}}))
(swap! ppl assoc-in ["persons" "bob"] {:age 11})
@ppl
{"persons" {"joe" {:age 1}, "bob" {:age 11}}}

user=> (def users [{:name "James" :age 26}  {:name "John" :age 43}])
#'user/users

user=> (update-in users [1 :age] inc)
[{:name "James", :age 26} {:name "John", :age 44}]

user=> (def p {:name "James" :age 26})
#'user/p

user=> (update-in p [:age] inc)
{:name "James", :age 27}

;; remember, the value of p hasn't changed!
user=> (update-in p [:age] + 10)
{:name "James", :age 36}

(defn char-cnt [s]
  "Counts occurence of each character in s"
  (reduce
    (fn [m k]
      (update-in m [k] (fnil inc 0)))
  {}
  (seq s)))

;Note use of fnil above - returns 0 if nil is passed to inc (avoids null pointer exception)
; f has args
user=> (update-in {:a 3} [:a] / 4 5)
{:a 3/20}

